package com.da.auth.security.jwt;

import com.alibaba.fastjson.JSON;
import com.da.auth.entity.constant.DailyAuthConstant;
import com.da.auth.entity.vo.UserDetailsVO;
import com.da.auth.security.jwt.JwtClaimsConstant;
import com.da.auth.security.jwt.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * @Author: hyacinth
 * @CreateTime: 2025-02-12
 * @Version: 1.0
 *
 *  * 拦截器在请求到达控制器之前执行，用于验证和刷新JWT令牌。
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class TokenInterceptor implements HandlerInterceptor {

    private final JwtUtils jwtUtils;

    /**
     * 拦截请求，验证和刷新JWT令牌。
     *
     * @param request  当前的HTTP请求
     * @param response 当前的HTTP响应
     * @param handler  处理程序对象
     * @return 如果请求通过验证和刷新，则返回true；否则返回false
     * @throws Exception 如果在处理请求时发生异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("<==========进入了TokenInterceptor.preHandle==========>");
        String token = request.getHeader(DailyAuthConstant.TOKEN_HEADER);
        Claims claims = jwtUtils.parseJWT(token);
        Object userInfoObj = claims.get(JwtClaimsConstant.USERINFO_LOGIN);
        String loginUserString = userInfoObj.toString();
        UserDetailsVO userDetailsVO = JSON.parseObject(loginUserString, UserDetailsVO.class);
        String redisToken = DailyAuthConstant.TOKEN_PREFIX + userDetailsVO.getId();
        if (token != null && jwtUtils.validateToken(redisToken)) {
            jwtUtils.refreshToken(redisToken);
            log.info("<==========离开TokenInterceptor.preHandle==========>");
            return true;
        }
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        log.info("<==========离开TokenInterceptor.preHandle==========>");
        return false;
    }
}
